
#include "stdafx.h"
#include "CallBackCode.h"
#include <winbase.h>
#include <vector>
#include <list>


class CallBackCodeManage 
{
	CallBackCodeManage(){}
	static CallBackCodeManage* p_m;
	std::list<CallBackCode*> m_mem;
public:
	void push_back(CallBackCode* val)
	{
		 m_mem.push_back(val);
	}

	static CallBackCodeManage* GetCallBackCodeManage()
	{
		if(!p_m)
		{
			p_m = new CallBackCodeManage;
		}
		return p_m;
	}
	
	static void release()
	{
		delete p_m;
		p_m = 0;
	}
};

CallBackCodeManage* CallBackCodeManage::p_m = 0;

void CallBackCodeRelease()
{
	CallBackCodeManage::release();
}

class CallBackCode::Impl 
{
public:
	Impl()
	{
		codedata = 0;
	}
	~Impl()
	{
		VirtualFree(codedata,0,MEM_RELEASE);
	}


	void Add32(__int32 a)
	{
		code.push_back(a);
		code.push_back(a>>8);
		code.push_back(a>>16);
		code.push_back(a>>24);

	}
	void Add8(__int8 a)
	{
		code.push_back(a);
	}

	void * GetFunction()
	{
		size = code.size();
		codedata = VirtualAlloc(0,size,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
		 __int8* cPos = (__int8*)codedata;
		for(std::vector<__int8>::iterator it = code.begin() ; it != code.end() ; ++it,++cPos)
		{
			* cPos = *it;
		}
		code.clear();
	    return codedata;
	}

	std::vector<__int8> code;

	void* codedata; 
	int size;
};



CallBackCode::CallBackCode()
{
	pImpl  = new Impl;
	CallBackCodeManage::GetCallBackCodeManage()->push_back(this);
}

CallBackCode::~CallBackCode()
{
	delete pImpl;
}

CallBackCode& CallBackCode::operator[]( __int32 a )
{
	pImpl->Add32(a);
	return *this;
}

CallBackCode& CallBackCode::operator()( __int8 a )
{
	pImpl->Add8(a);
	return *this;
}

void * CallBackCode::GetFunction()
{
	return pImpl->GetFunction();
}

